package com.echo.code.thread;

import static java.util.concurrent.ThreadLocalRandom.current;

import com.echo.code.thread.lock.Lock;
import com.echo.code.thread.lock.impl.SimpleLock;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import org.junit.Test;

/**
 * TestCase
 */
public class LockTestCase {

  public static final Lock LOCK = new SimpleLock();

  @Test
  public static void lockTestCase() {
    IntStream.range(0, 10).mapToObj(i -> new Thread(() -> {
      try {
        LOCK.lock();
        TimeUnit.SECONDS.sleep(current().nextInt(10));
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        // 避免死锁
        LOCK.unlock();
      }
    })).forEach(Thread::start);
  }

  @Test
  public static void readAndWriteLockTestCase() {
    // size is 50
    final ShareData shareData = new ShareData(10);
    IntStream.range(0, 10).mapToObj(i -> new Thread(() -> {
      try {
        Character[] characters = shareData.read();
        System.out.println(Thread.currentThread().getName() + ": " + Arrays.toString(characters));
      } catch (InterruptedException e) {
      }
    })).forEach(Thread::start);

    // 创建5个线程进行数据写入操作
    IntStream.range(0, 5).mapToObj(i -> new Thread(() -> {
      try {
        shareData.write("hello".charAt(i));
      } catch (InterruptedException e) {
      }
    })).forEach(Thread::start);
  }

  public static void main(String[] args) {
    // lockTestCase();
    readAndWriteLockTestCase();
  }
}

